package ru.st.sel.dudarko;

import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;

import org.testng.*;
import org.testng.annotations.*;

import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;

import org.openqa.selenium.*;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

import java.util.Random;
import java.util.List;
import java.util.Collections;

public class HW_3 extends ru.st.sel.dudarko.pages.TestBase {
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();
  
  @Test
  public void testAddPositiveFilm() throws Exception {
	System.out.println("testAddPositiveFilm");
	//Login to site with desired login/pass
	login(baseUrl + "/php4dvd/","adder","adder");
	//Toggle add movie
	driver.findElement(By.cssSelector("img[alt=\"Add movie\"]")).click();
    //Generate random number
	Random r = new Random();
    int num = 1 + (int)(r.nextFloat() * 1000);
    String str = String.valueOf(num);
    //Input info
    inputwithnumber("Film number "+str,String.valueOf(num+1014),"Blueray",str);
    //Check that we was successful
    String error=error();
    //If we got no error than we'll check that film was added
    if (error == null) {error = searchfilm("Film number "+str);}
    //Log out
    driver.findElement(By.linkText("Log out")).click();
    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to log out[\\s\\S]$"));
    //If we had error - return error
    assertTrue(error,error == null);
    //The end
  }

  @Test
  public void testAddNonameFilm() throws Exception {
    System.out.println("testAddNonameFilm");    
	//Login to site with desired login/pass
	login(baseUrl + "/php4dvd/","adder","adder");
	//Getting count of films
	int filmscount1=filmscount();
	//Toggle add movie
	driver.findElement(By.cssSelector("img[alt=\"Add movie\"]")).click();
    //Generate random number
	Random r = new Random();
    int num = 1 + (int)(r.nextFloat() * 1000);
    String str = String.valueOf(num);
    //Input info
    inputwithnumber("",String.valueOf(num+1014),"Blueray",str);
    //Check error on page
    String error=null;
    if (error() == null) {error = "Error not found";}
    //Check that films count was not changed
    int filmscount2=filmscount();
	if ((filmscount1 != filmscount2) & (error==null)) {error = "Films count was changed. Was="+filmscount1+" Now="+filmscount2;}
    //Log out
    driver.findElement(By.linkText("Log out")).click();
    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to log out[\\s\\S]$"));
    //If we had error - return error
    assertTrue(error,error == null);
    //The end
  }  
  
  @Test
  public void testAddNoyearFilm() throws Exception {
	System.out.println("testAddNoyearFilm");        
	//Login to site with desired login/pass
	login(baseUrl + "/php4dvd/","adder","adder");
	//Getting count of films
	int filmscount1=filmscount();
	//Toggle add movie
	driver.findElement(By.cssSelector("img[alt=\"Add movie\"]")).click();
    //Generate random number
	Random r = new Random();
    int num = 1 + (int)(r.nextFloat() * 1000);
    String str = String.valueOf(num);
    //Input info
    inputwithnumber("Film number "+str,"","Blueray",str);
    //Check that we was successful
    String error=null;
    if (error() == null) {error = "Error not found";}
    //Check that films count was not changed
    int filmscount2=filmscount();
	if ((filmscount1 != filmscount2) & (error==null)) {error = "Films count was changed. Was="+filmscount1+" Now="+filmscount2;}
    //Log out
    driver.findElement(By.linkText("Log out")).click();
    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to log out[\\s\\S]$"));
    //If we had error - return error
    assertTrue(error,error == null);
    //The end
  }    
  
  @Test
  public void testAddNoformatFilm() throws Exception {
		System.out.println("testAddNoformatFilm");    
	//Login to site with desired login/pass
	login(baseUrl + "/php4dvd/","adder","adder");
	//Getting count of films
	int filmscount1=filmscount();
	//Toggle add movie
	driver.findElement(By.cssSelector("img[alt=\"Add movie\"]")).click();
    //Generate random number
	Random r = new Random();
    int num = 1 + (int)(r.nextFloat() * 1000);
    String str = String.valueOf(num);
    //Input info
    inputwithnumber("Film number "+str,String.valueOf(num+1014),"",str);
    //Check that we was successful
    String error=null;
    if (error() == null) {error = "Error not found";}
    //Check that films count was not changed
    int filmscount2=filmscount();
	if ((filmscount1 != filmscount2) & (error==null)) {error = "Films count was changed. Was="+filmscount1+" Now="+filmscount2;}
    //Log out
    driver.findElement(By.linkText("Log out")).click();
    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to log out[\\s\\S]$"));
    //If we had error - return error
    assertTrue(error,error == null);
    //The end
  }    
  
  @Test
  public void testDeleteFilm() throws Exception {
		System.out.println("testDeleteFilm");    
	//Login to site with desired login/pass
	login(baseUrl + "/php4dvd/","deleter","deleter");
	//Getting list with films
	driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
	List<WebElement> elements = driver.findElements(By.cssSelector("a[href*='go=movie&id=']"));
	driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	String error=null;
	//Checking that we got any films here
	if (elements.size() > 0) {
		//Shuffling elements in list for random film
		Collections.shuffle(elements);
		//Getting name of the film
		String filmtodelete = elements.get(0).getText();
		//Going into
		elements.get(0).click();
		//Toggle click to delete
	    driver.findElement(By.cssSelector("img[alt=\"Remove\"]")).click();
	    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to remove this[\\s\\S]$"));
	    //Check that we really deleted this film
	    if (searchfilm(filmtodelete) == null) {
	    	error = "Film '"+filmtodelete+"' was not deleted";
	    }
	} else {
		error = "No films found to delete";
	}
	//Log out
    driver.findElement(By.linkText("Log out")).click();
    assertTrue(closeAlertAndGetItsText().matches("^Are you sure you want to log out[\\s\\S]$"));
    //If we had error - return error
    assertTrue(error,error == null);    
    //The end
  } 
  
  private int filmscount() {
	  //Go back to home
	  driver.findElement(By.linkText("Home")).click();
	  //Getting count of films
	  driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
	  List<WebElement> elements = driver.findElements(By.cssSelector("a[href*='go=movie&id=']"));
	  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	  return elements.size();
  }
  
  private String searchfilm(String filmname) {
	  //Go back to home
	  driver.findElement(By.linkText("Home")).click();
	  //Find films with this name
	  driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
	  List<WebElement> elements = driver.findElements(By.xpath("//div[contains(text(), '"+filmname+"')]"));
	  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	  if (elements.size() > 0) {
		  driver.findElement(By.xpath("//div[contains(text(), '"+filmname+"')]")).click();
	  } else {
		  return "No films found";
	  }
	  return null;
  }
  
  private String error() {
	  //Check that we have no errors on page
	  driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
	  if (isElementPresent(By.cssSelector("label[class=\"error\"]"))) {
		  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		  return driver.findElement(By.cssSelector("label[class=\"error\"]")).getAttribute("textContent");
	  }
	  driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	  return null;
  }
  
  private void login(String loginsite,String loginname,String loginpass) {
	  driver.get(loginsite);
	  driver.findElement(By.id("username")).clear();
	  driver.findElement(By.id("username")).sendKeys(loginname);
	  driver.findElement(By.name("password")).clear();
	  driver.findElement(By.name("password")).sendKeys(loginpass);
	  driver.findElement(By.name("submit")).click();
  }
  
  private void inputwithnumber(String title, String year, String format, String inputstr) {
		driver.findElement(By.name("imdbid")).clear();
	    driver.findElement(By.name("imdbid")).sendKeys(inputstr);
	    driver.findElement(By.name("name")).clear();
	    driver.findElement(By.name("name")).sendKeys(title);
	    driver.findElement(By.name("aka")).clear();
	    driver.findElement(By.name("aka")).sendKeys("Film Alt #"+inputstr);
	    driver.findElement(By.name("year")).clear();
	    driver.findElement(By.name("year")).sendKeys(year);
	    driver.findElement(By.name("duration")).clear();
	    driver.findElement(By.name("duration")).sendKeys("101");
	    driver.findElement(By.name("rating")).clear();
	    driver.findElement(By.name("rating")).sendKeys("1");
	    driver.findElement(By.id("formats")).clear();
	    driver.findElement(By.id("formats")).sendKeys(format);   
	    driver.findElement(By.id("own_yes")).click();
	    driver.findElement(By.id("seen_no")).click();
	    driver.findElement(By.id("loaned_yes")).click();
	    driver.findElement(By.name("loanname")).clear();
	    driver.findElement(By.name("loanname")).sendKeys("Loaner");
	    driver.findElement(By.name("loandate")).clear();
	    driver.findElement(By.name("loandate")).sendKeys("2014-08-11");   
	    driver.findElement(By.id("cover")).sendKeys("C:\\Users\\Public\\Pictures\\Sample Pictures\\Lighthouse.jpg");
	    driver.findElement(By.name("trailer")).clear();
	    driver.findElement(By.name("trailer")).sendKeys("http://notrailer.org/");
	    driver.findElement(By.name("notes")).clear();
	    driver.findElement(By.name("notes")).sendKeys("Nonotes Film #"+inputstr);
	    driver.findElement(By.name("taglines")).clear();
	    driver.findElement(By.name("taglines")).sendKeys("Taglines");
	    driver.findElement(By.name("plotoutline")).clear();
	    driver.findElement(By.name("plotoutline")).sendKeys("Plot outline");
	    driver.findElement(By.name("plots")).clear();
	    driver.findElement(By.name("plots")).sendKeys("Plots");
	    driver.findElement(By.id("text_languages_0")).clear();
	    driver.findElement(By.id("text_languages_0")).sendKeys("Langs");
	    driver.findElement(By.name("subtitles")).clear();
	    driver.findElement(By.name("subtitles")).sendKeys("Subs");
	    driver.findElement(By.name("audio")).clear();
	    driver.findElement(By.name("audio")).sendKeys("Audio");
	    driver.findElement(By.name("video")).clear();
	    driver.findElement(By.name("video")).sendKeys("Video");
	    driver.findElement(By.name("country")).clear();
	    driver.findElement(By.name("country")).sendKeys("Contry");
	    driver.findElement(By.name("genres")).clear();
	    driver.findElement(By.name("genres")).sendKeys("Genres");
	    driver.findElement(By.name("director")).clear();
	    driver.findElement(By.name("director")).sendKeys("Direcotr");
	    driver.findElement(By.name("writer")).clear();
	    driver.findElement(By.name("writer")).sendKeys("Writer");
	    driver.findElement(By.name("producer")).clear();
	    driver.findElement(By.name("producer")).sendKeys("Producer");
	    driver.findElement(By.name("music")).clear();
	    driver.findElement(By.name("music")).sendKeys("Music");
	    driver.findElement(By.name("cast")).clear();
	    driver.findElement(By.name("cast")).sendKeys("Cast");
	    driver.findElement(By.id("submit")).click();
  }  
  
  boolean isElementPresent(By locator) {
	    return driver.findElements(locator).size() > 0;
  }


  private String closeAlertAndGetItsText() {
	   try {
		  Alert alert = driver.switchTo().alert();
		  String alertText = alert.getText();
		  if (acceptNextAlert) {
		    alert.accept();
		  } else {
		    alert.dismiss();
		  }
		  return alertText;
		} finally {
		  acceptNextAlert = true;
		}
	  }
  }